package cn.chinasyq.photoquan.util;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.net.Uri;
import android.provider.MediaStore;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 一搏 on 2015/11/27.
 */
public class BitmapUtil {
    private static String att;

    public static boolean saveBitmapToFile(Bitmap bitmap, String dstFile
    ) {
        boolean isSaveSuccessed = false;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        try {
            FileOutputStream out = new FileOutputStream(dstFile);
            out.write(baos.toByteArray());
            out.flush();
            out.close();
            isSaveSuccessed = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return isSaveSuccessed;
    }

    public static String readEXIF(String path) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ExifInterface exifInterface = new ExifInterface(path);
        Class exif = ExifInterface.class;
        Method getAttributesNative = exif.getDeclaredMethod("getAttributesNative", String.class);
        getAttributesNative.setAccessible(true);
        String attr = (String) getAttributesNative.invoke(exifInterface, path);
        return attr;
    }

    public static Bitmap decodeUriAsBitmap(Context context, Uri uri) {
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(context.getContentResolver()
                    .openInputStream(uri));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return bitmap;
    }

    public static String convertUri2FilePath(Context c, Uri uri) {
        if (null == uri) return null;
        final String scheme = uri.getScheme();
        String data = null;
        if (scheme == null)
            data = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = c.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    if (index > -1) {
                        data = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        return data;
    }

    public static Bitmap convertUri2Bitmap(Activity activity, Uri uri) {
        byte[] mContent = null;
        try {
            // 将图片内容解析成字节数组
            InputStream inputStream = activity.getContentResolver()
                    .openInputStream(Uri.parse(uri.toString()));
            mContent = readStream(inputStream);
            inputStream.close();
        } catch (Exception e) {
        }
        // 将字节数组转换为ImageView可调用的Bitmap对象
        return getPicFromBytes(mContent, null);
    }

    public static byte[] readStream(InputStream inStream) throws Exception {
        byte[] buffer = new byte[1024];
        int len = -1;
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        byte[] data = outStream.toByteArray();
        outStream.close();
        return data;
    }

    public static Bitmap getPicFromBytes(byte[] bytes,
                                         BitmapFactory.Options opts) {
        if (bytes != null) {
            if (opts != null)
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length,
                        opts);
            else
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        } else {
            return null;
        }
    }

    //计算图片的缩放值
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    // 根据路径获得图片并压缩，返回bitmap用于显示
    public static Bitmap getSmallBitmap(String filePath, int reqWidth, int reqHeight) {

        try {
                att = readEXIF(filePath);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        saveBitmapToFile(BitmapFactory.decodeFile(filePath, options), filePath);
        try {
            writeEXIF(filePath,att);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return BitmapFactory.decodeFile(filePath);
    }

    public final static Bitmap compressBitmap(String filePath, long maxBytes) {
        try {
            try {
                 att = readEXIF(filePath);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            Bitmap bitmap = BitmapFactory.decodeFile(filePath);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            int options = 95;
            while (baos.size()> maxBytes * 1024) {
                baos.reset();
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
                options -= 5;
            }
            byte[] bts = baos.toByteArray();
            Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length);
            baos.close();
            saveBitmapToFile(bmp, filePath);
            try {
                writeEXIF(filePath,att);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return bmp;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    public static int[] getImageWHmatcher(String url) {

        int[] xy = new int[2];
        if (url == null) {
            return xy;
        }
        Pattern dimension = Pattern.compile("_(\\d+)_(\\d+)\\.");
        Matcher dim_matcher = dimension.matcher(url);

        // Find all matches
        while (dim_matcher.find()) {
            // Get the matching string
            xy[0] = Integer.parseInt(dim_matcher.group(1));
            xy[1] = Integer.parseInt(dim_matcher.group(2));
        }
        return xy;
    }

    public static Uri convertBitmap2Uri(Context c, Bitmap bitmap) {
        if (bitmap != null) {
            return Uri.parse(MediaStore.Images.Media.insertImage(
                    c.getContentResolver(),
                    bitmap, null, null));
        } else {
            return null;
        }
    }

    public static void writeEXIF(String path, String attr) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ExifInterface exifInterface = new ExifInterface(path);
        Class exif = ExifInterface.class;
        Method saveAttributesNative = exif.getDeclaredMethod("saveAttributesNative", String.class, String.class);
        saveAttributesNative.setAccessible(true);
        Method commitChangesNative = exif.getDeclaredMethod("commitChangesNative", String.class);
        commitChangesNative.setAccessible(true);
        saveAttributesNative.invoke(exifInterface, path, attr);
        commitChangesNative.invoke(exifInterface, path);
    }
}
